home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 5 / The 640 Meg Shareware Studio CD-ROM Volume V (Data Express)(1994).ISO / amiga / tolleuhr.lha / TolleUhr / TolleUhr.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  42KB  |  1,276 lines

  1. #define VERSION "1.1"
  2.  
  3. /***************************************************************************
  4. *                                  *                                       *
  5. * Programm: TolleUhr               * Version: s.o.                         *
  6. *                                  *                                       *
  7. ****************************************************************************
  8. *                                                                          *
  9. * Dieses Programm ist Public-Domain, d.h. wer immer Lust dazu hat, darf    *
  10. * dieses Programm kopieren, umschreiben, usw., vorausgesetzt:              *
  11. *                                                                          *
  12. * 1. Die Autorenliste bleibt voll erhalten. (auch in About-Requestern)     *
  13. * 2. Wer etwas am Programm verbricht, mu▀ sich auch dazuschreiben.         *
  14. *                                                                          *
  15. * Es wird keine Haftung fⁿr SchΣden irgendwelcher Art ⁿbernommen.          *
  16. *                                                                          *
  17. * Autor: Matthias Fleischer  Adlerstra▀e 30 7302 Ostfildern 2              *
  18. *        (fleischr@izfm.uni-stuttgart.de)                                  *
  19. *        .                                                                 *
  20. *        .(Auf Paul, schaff was !)                                         *
  21. *                                                                          *
  22. *                                                                          *
  23. *                                                                          *
  24. ***************************************************************************/
  25.  
  26. /**** includes ****/
  27.  
  28. #include <exec/memory.h>
  29. #include <clib/exec_protos.h>
  30. #include <dos/exall.h>
  31. #include <clib/dos_protos.h>
  32. #include <clib/alib_protos.h>
  33. #include <clib/alib_stdio_protos.h>
  34. #include <graphics/scale.h>
  35. #include <graphics/graphint.h>
  36. #include <graphics/gfxmacros.h>
  37. #include <clib/graphics_protos.h>
  38. #include <clib/gadtools_protos.h>
  39. #include <intuition/cghooks.h>
  40. #include <intuition/classes.h>
  41. #include <intuition/gadgetclass.h>
  42. #include <clib/intuition_protos.h>
  43. #include <workbench/startup.h>
  44. #include <clib/icon_protos.h>
  45. #include <devices/audio.h>
  46. extern void exit(int);
  47.  
  48. /**** Sonstiges ****/
  49.  
  50. char version[]="$VER: Version "VERSION"\n\015";
  51. char aboutstring[]="TolleUhr Version "VERSION" by M.Fleischer in 1993";
  52.  
  53. typedef struct IORequest *iorequest;
  54. typedef struct timerequest *iotime;
  55. typedef struct IOAudio *ioaudio;
  56.  
  57. /**** Eigene Prototypen ****/
  58.  
  59. void wbmain(struct WBStartup *message);
  60. void main(int argc,char *argv[]);
  61. void mergetooltypes(struct WBStartup *args);
  62. void parsecliargs(char *argstring,int laenge);
  63. int xtod(int a);
  64. void setargs(void);
  65. void setpattern(void);
  66. void readstr(char *dest,char *sorc,int n);
  67. int nexttick(void);
  68. void openlibs(void);
  69. void openall(void);
  70. void closeall(int retval);
  71. void newsize1(void); /* L÷scht BitPlanes */
  72. void newsize2(void); /* Holt BitPlanes */
  73. void zifferblatt (void);
  74. void rahmen(void);
  75. void zeichnen(void);
  76. void zeiger(ULONG winkel,int lfactor,int offset,int apen,int open);
  77. void getcolor(UBYTE *color);
  78. void setalarm(void);
  79. void cdtoicon(struct WBStartup *args);
  80. void saveprefs(char *myname);
  81. void setstr(char *dest,UBYTE *sourc,int n);
  82. int dtox(int a);
  83. void testifalarm(void);
  84. void starttune(UWORD *tune);
  85. void playnote(void);
  86. void endtune(void);
  87. struct Window *creatertrequest
  88. ( struct TagItem windowtags[],int anzgadgets,struct TagItem *gadgettags[],
  89.   struct NewGadget gadgets[],ULONG edge[][3],struct Gadget **glistpointer);
  90.  
  91. /**** Ressourcen mⁿssen global sein (wegen cleanup) ****/
  92.  
  93. struct Library *DOSBase=NULL;
  94. struct Library *GfxBase=NULL;
  95. struct Library *IntuitionBase=NULL;
  96. struct Library *GadToolsBase=NULL;
  97. struct Library *IconBase=NULL;
  98. struct Screen *pubscreen=NULL; /* Den blocken wir */
  99. struct Window *mywindow=NULL; /* 1 Fenster */
  100. struct IntuiMessage *msg; /* Fⁿr Gadgets */
  101. struct Menu *menus=NULL;
  102. APTR visi=NULL;
  103. struct MsgPort *tport=NULL; /* Timer */
  104. iotime treq=NULL;
  105. int notime=1;
  106. int timesent=0;
  107. char *string=NULL; /* fⁿr ToolTypes */
  108. ULONG strln=1;
  109. struct DiskObject *dobj=NULL;
  110. APTR buf=NULL; /* BitPlane fⁿr Area-Befehle */
  111. struct MsgPort *audport=NULL; /* Alles fⁿr audio.device */
  112. ioaudio audreq[2]={ NULL,NULL };
  113. int noaudio=1; /* device ge÷ffnet ? */
  114. int nosound=1; /* Soundkanal geholt ? */
  115. int audsent[2]={ 0,0 }; /* Sound gespielt ? */
  116. BYTE *waveform=NULL;
  117. LONG oldpri; /* Task-Priority */
  118. int changedpri=0;
  119.  
  120. /**** Voreinstellungen ****/
  121.  
  122. long links =50;
  123. long oben  =50;
  124. long breite=108;
  125. long hoehe =54;
  126. int sekunden=0;
  127. int oval=0;
  128. int zeigen=1;
  129. int zeigertyp=2;
  130. int zeigerbreite=2;
  131. int schatten=0;
  132. int rahmenanz=3;
  133. UBYTE pens[]={ 2,0,2,0,2,1,2,2,2,2,0,1,2,3 };
  134.              /* sec,mina,mino,stda,stdo,shdw,12,1/4,1/12,1/60,b0,b1,b2,b3 */
  135. UBYTE must[]={ 0,0,0,0 };
  136. ULONG almin=0,alstd=12; /* Alarmzeit */
  137. int smarthour=0;
  138. int alarm=0;
  139. int chime=0;
  140.  
  141. /**** Globale Variablen ****/
  142.  
  143. ULONG maskx,masky;
  144. UWORD muster[8][2];
  145. int doublex,doubley;
  146. long xoffset,yoffset;
  147. long boleft,botop,breit2,hoehe2;
  148. long hires,interlace,active=0;
  149. ULONG std,min,sec;
  150. long redrawx1,redrawx2,redrawy1,redrawy2; /* Gezeichneter Bereich bezogen
  151.                                              auf Fensterkoordinaten */
  152. struct IntuiText about=
  153. { 0,0,JAM1,15,5,NULL,aboutstring,NULL }, /* About-Text */
  154.                  oktext=
  155. { 0,0,JAM1,6,3,NULL,"OK",NULL }; /* OK-Text */
  156. struct TagItem notags[]={ TAG_DONE,1 }; /* Leeres TagItem-Feld */
  157. struct RastPort *rport1; /* Fenster */
  158. struct BitMap abitmap; /* Buffer */
  159. struct RastPort rport2;
  160. struct TmpRas temp; /* Fⁿr Area-Befehle */
  161. struct AreaInfo info;
  162. SHORT table[12]; /* Fⁿr Area-Befehle */
  163. UWORD *playtune;
  164. struct TextAttr topaz={ "topaz.font",8,FS_NORMAL,FPF_ROMFONT };
  165. struct RDArgs args={ NULL,0,0,0,NULL,0,NULL,0 };
  166. ULONG ergebnis[20]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  167.  
  168. /**** Tabellen ****/
  169.  
  170. long handwidth[]={ 4000,3250,2500,1750,1000 };
  171.  
  172. long sizes[][4]={ 0,0,3,2, -3,0,3,2, -3,-2,3,2, 0,2,0,-4 }; /* Fⁿr Gadgets */
  173.  
  174. struct Gadget gadgets[]={
  175. { &gadgets[1],0,0,1,1,GADGHNONE,
  176.   0,CLOSE,NULL,NULL,NULL,0,NULL,0,NULL },         /* Schlie▀-Gadget */
  177. { &gadgets[2],0,0,1,1,GADGHNONE|GRELRIGHT,
  178.   0,WUPFRONT,NULL,NULL,NULL,0,NULL,0,NULL },      /* Tiefen-Gadget */
  179. { &gadgets[3],0,0,1,1,GADGHNONE|GRELRIGHT|GRELBOTTOM,
  180.   0,SIZING,NULL,NULL,NULL,0,NULL,0,NULL },        /* Gr÷▀en-Gadget */
  181. { NULL       ,0,0,1,1,GADGHNONE|GRELWIDTH|GRELHEIGHT,
  182.   0,WDRAGGING,NULL,NULL,NULL,0,NULL,0,NULL } };   /* Zieh-Gadget */
  183.  
  184. struct TagItem windowtags[]=
  185. { WA_Left,0,WA_Top,0,WA_Width,0,WA_Height,0, /* Fensterkoordinaten (s.u.) */
  186.   WA_PubScreen,0, /* kommt spΣter rein */
  187.   WA_MinWidth,10,WA_MinHeight,10,WA_MaxWidth,-1,WA_MaxHeight,-1,
  188.   WA_Gadgets,(ULONG)gadgets,                 /* Liste von Gadgets */
  189.   WA_Borderless,1,                           /* Rahmen mach ich selber */
  190.   WA_SimpleRefresh,1,                        /* Spart CHIP-MEM */
  191.   WA_IDCMP,NEWSIZE|CLOSEWINDOW|MENUPICK|REFRESHWINDOW|
  192.            ACTIVEWINDOW|INACTIVEWINDOW,          /* Message-Port */
  193.   WA_ScreenTitle,(ULONG)aboutstring,
  194.   TAG_DONE,1 };
  195.  
  196. struct NewMenu menulist[]= /* Liste von Menus */
  197. { { NM_TITLE,"Project",  NULL,0,0,NULL },
  198.   { NM_ITEM, "About",    NULL,0,0,NULL },
  199.   { NM_ITEM, "Save Prefs",NULL,0,0,NULL },
  200.   { NM_ITEM, "Quit",     NULL,0,0,NULL },
  201.   { NM_TITLE,"Settings", NULL,0,0,NULL },
  202.   { NM_ITEM, "Seconds",  NULL,CHECKIT|MENUTOGGLE,0,NULL },
  203.   { NM_ITEM, "Oval",     NULL,CHECKIT|MENUTOGGLE,0,NULL },
  204.   { NM_ITEM, "Show",     NULL,0,0,NULL },
  205.   { NM_SUB,  "Minutes",  NULL,CHECKIT,2|4|8|16,NULL },
  206.   { NM_SUB,  "Hours",    NULL,CHECKIT,1|4|8|16,NULL },
  207.   { NM_SUB,  "Quarter",  NULL,CHECKIT,1|2|8|16,NULL },
  208.   { NM_SUB,  "One",      NULL,CHECKIT,1|2|4|16,NULL },
  209.   { NM_SUB,  "None",     NULL,CHECKIT,1|2|4| 8,NULL },
  210.   { NM_ITEM, "Hands",    NULL,0,0,NULL },
  211.   { NM_SUB,  "Line",     NULL,CHECKIT,2|4|8,NULL },
  212.   { NM_SUB,  "Triangle", NULL,CHECKIT,1|4|8,NULL },
  213.   { NM_SUB,  "Rhombus",  NULL,CHECKIT,1|2|8,NULL },
  214.   { NM_SUB,  "Rectangle",NULL,CHECKIT,1|2|4,NULL },
  215.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  216.   { NM_SUB,  "Very Thin",NULL,CHECKIT,64|128|256|512,NULL },
  217.   { NM_SUB,  "Thin",     NULL,CHECKIT,32|128|256|512,NULL },
  218.   { NM_SUB,  "Normal",   NULL,CHECKIT,32|64|256|512,NULL },
  219.   { NM_SUB,  "Thick",    NULL,CHECKIT,32|64|128|512,NULL },
  220.   { NM_SUB,  "Very Thick",NULL,CHECKIT,32|64|128|256,NULL },
  221.   { NM_ITEM, "Shadow",   NULL,CHECKIT|MENUTOGGLE,0,NULL },
  222.   { NM_ITEM, "Border",   NULL,0,0,NULL },
  223.   { NM_SUB,  "None",     NULL,CHECKIT,2|4,NULL },
  224.   { NM_SUB,  "Single",   NULL,CHECKIT,1|4,NULL },
  225.   { NM_SUB,  "Double",   NULL,CHECKIT,1|2,NULL },
  226.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  227.   { NM_SUB,  "Hires",    NULL,CHECKIT|MENUTOGGLE,0,NULL },
  228.   { NM_SUB,  "Interlace",NULL,CHECKIT|MENUTOGGLE,0,NULL },
  229.   { NM_ITEM, "Chime",    NULL,0,0,NULL },
  230.   { NM_SUB,  "None",     NULL,CHECKIT,2|4,NULL },
  231.   { NM_SUB,  "Hours",    NULL,CHECKIT,1|4,NULL },
  232.   { NM_SUB,  "Quarter",  NULL,CHECKIT,1|2,NULL },
  233.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  234.   { NM_SUB,  "Smart",    NULL,CHECKIT|MENUTOGGLE,0,NULL },
  235.   { NM_ITEM, "Alarm",    NULL,0,0,NULL },
  236.   { NM_SUB,  "Set",      NULL,0,0,NULL },
  237.   { NM_SUB,  "On",       NULL,CHECKIT|MENUTOGGLE,0,NULL },
  238.   { NM_TITLE,"Colors",   NULL,0,0,NULL }, /* Colours Menu */
  239.   { NM_ITEM, "Seconds",  NULL,0,0,NULL },
  240.   { NM_ITEM, "Min. APen",NULL,0,0,NULL },
  241.   { NM_ITEM, "Min. OPen",NULL,0,0,NULL },
  242.   { NM_ITEM, "Hour APen",NULL,0,0,NULL },
  243.   { NM_ITEM, "Hour OPen",NULL,0,0,NULL },
  244.   { NM_ITEM, "Shadow",   NULL,0,0,NULL },
  245.   { NM_ITEM, "12",       NULL,0,0,NULL },
  246.   { NM_ITEM, "Quarter",  NULL,0,0,NULL },
  247.   { NM_ITEM, "Hours",    NULL,0,0,NULL },
  248.   { NM_ITEM, "Minutes",  NULL,0,0,NULL },
  249.   { NM_ITEM, "Border 0", NULL,0,0,NULL },
  250.   { NM_ITEM, "Border 1", NULL,0,0,NULL },
  251.   { NM_ITEM, "Border 2", NULL,0,0,NULL },
  252.   { NM_ITEM, "Border 3", NULL,0,0,NULL },
  253.   { NM_TITLE,"Pattern",  NULL,0,0,NULL },
  254.   { NM_ITEM, "Color 0",  NULL,0,0,NULL },
  255.   { NM_ITEM, "Color 1",  NULL,0,0,NULL },
  256.   { NM_ITEM, "Color 2",  NULL,0,0,NULL },
  257.   { NM_ITEM, "Color 3",  NULL,0,0,NULL },
  258.   { NM_END,NULL,NULL,0,0,NULL } };
  259.  
  260. BYTE sinus[]= /* sinus-Tabelle */
  261. { 0,13,26,39,52,64,75,85,94,103,110,116,121,124,126,
  262.   127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  263.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  264.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13 },
  265.      cosinus[]= /* cosinus-Tabelle */
  266. { 127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  267.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  268.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13,
  269.   0,13,26,39,52,64,75,85,94,103,110,116,121,124,126 };
  270.  
  271. BYTE srect[]= /* Fⁿr rechteckiges Zifferblatt */
  272. { 0,13,27,41,57,73,92,111,124,127,127,127,127,127,127,
  273.   127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  274.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  275.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13 },
  276.      crect[]=
  277. { 127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  278.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  279.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13,
  280.   0,13,27,41,57,73,92,111,124,127,127,127,127,127,127 };
  281.  
  282. UBYTE pent[]={ 6,8,8,7,8,8,7,8,8,7,8,8 }; /* Pen-Tabelle f. Zifferblatt */
  283.  
  284. BYTE dx1[]= /* Daten fⁿr Zifferblatt */
  285. { -2, 2, 1,-2, 1, 2,-2,-2,-1,-2,-1,-2 },
  286.      dy1[]=
  287. { -4,-1,-2,-2, 2, 1,-2, 1, 2,-2,-2,-1 },
  288.      dx2[]=
  289. {  4,-2, 1, 4, 1,-2, 4, 2,-1, 4,-1, 2 },
  290.      dy2[]=
  291. {  0, 3, 2, 0,-2,-3, 0,-3,-2, 0, 2, 3 },
  292.      dx3[]=
  293. {  0,-2,-3, 0,-3,-2, 0, 2, 3, 0, 3, 2 },
  294.      dy3[]=
  295. {  8,-1, 2, 4,-2, 1, 4, 1,-2, 4, 2,-1 },
  296.      dx4[]=
  297. { -4, 2,-1,-4,-1, 2,-4,-2, 1,-4, 1,-2 },
  298.      dy4[]=
  299. {  0,-3,-2, 0, 2, 3, 0, 3, 2, 0,-2,-3 };
  300.  
  301.   /* Requester 1 */
  302. struct TagItem window2tags[]= /* Palette-Requester */
  303. { WA_Gadgets,0, /* kommen spΣter rein */
  304.   WA_PubScreen,0, /* das auch */
  305.   WA_Left,100,WA_Top,100,WA_InnerWidth,144,WA_InnerHeight,72, /* Fensterkoordinaten */
  306.   WA_IDCMP,CLOSEWINDOW|PALETTEIDCMP,         /* Message-Port */
  307.   WA_Title,(ULONG)"Choose one:",
  308.   WA_ScreenTitle,(ULONG)aboutstring,
  309.   WA_DepthGadget,1,WA_CloseGadget,1,WA_DragBar,1,WA_Activate,1,
  310.   TAG_DONE,1 };
  311.  
  312. ULONG window2goff[][3]=
  313. { 4,2,PALETTE_KIND };
  314.  
  315. struct NewGadget window2gad[]=
  316. { 0,0,136,68,NULL,NULL,0,0,NULL,0 };
  317.  
  318. struct TagItem window2gadtags1[]=
  319. { GTPA_Depth,0,TAG_DONE,1 };
  320.  
  321. struct TagItem *window2gadtags[]=
  322. { window2gadtags1 };
  323.  
  324.   /* Requester 2 */
  325. struct TagItem window3tags[]= /* Alarmzeit-Requester */
  326. { WA_Gadgets,0, /* kommen spΣter rein */
  327.   WA_PubScreen,0, /* das auch */
  328.   WA_Left,100,WA_Top,100,WA_InnerWidth,144,WA_InnerHeight,72,
  329.   WA_IDCMP,CLOSEWINDOW|BUTTONIDCMP|SLIDERIDCMP,
  330.   WA_Title,(ULONG)"Alarm",
  331.   WA_ScreenTitle,(ULONG)aboutstring,
  332.   WA_DepthGadget,1,WA_CloseGadget,1,WA_DragBar,1,WA_Activate,1,
  333.   TAG_DONE,1 };
  334.  
  335. ULONG window3goff[][3]=
  336. { { 42,15,SLIDER_KIND },
  337.   { 82,15,SLIDER_KIND },
  338.   {  2,58,BUTTON_KIND },
  339.   { 76,58,BUTTON_KIND } };
  340.  
  341. struct NewGadget window3gad[]=
  342. { { 0,0,20,39,NULL,    &topaz,1,0,NULL,0 },
  343.   { 0,0,20,39,NULL,    &topaz,2,0,NULL,0 },
  344.   { 0,0,66,12,"Use",   &topaz,3,0,NULL,0 },
  345.   { 0,0,66,12,"Cancel",&topaz,4,0,NULL,0 } };
  346.  
  347. struct TagItem window3gadtags1[]=
  348. { GTSL_Level,1,PGA_Freedom,LORIENT_VERT,GTSL_LevelPlace,PLACETEXT_ABOVE,
  349.   GTSL_MaxLevelLen,10,GTSL_Min,1,GTSL_Max,12,GTSL_LevelFormat,
  350.   (ULONG)"   %2ld : ",/*GA_RelVerify,1,*/TAG_DONE,1 },
  351.                window3gadtags2[]=
  352. { GTSL_Level,0,PGA_Freedom,LORIENT_VERT,GTSL_LevelPlace,PLACETEXT_ABOVE,
  353.   GTSL_MaxLevelLen,5,GTSL_Min,0,GTSL_Max,59,GTSL_LevelFormat,
  354.   (ULONG)"%02ld",GA_RelVerify,1,TAG_DONE,1 };
  355.  
  356. struct TagItem *window3gadtags[]=
  357. { window3gadtags1,window3gadtags2,notags,notags };
  358.  
  359. UBYTE camap[]={ 1,2,4,8 }; /* Sound Channel Allocation Map */
  360.  
  361. UWORD alarmtune[]={ 800,800,800,800,800,800,800,1600,
  362.                     800,800,800,800,800,800,800,1600,
  363.                     800,800,800,800,800,800,800,1600,
  364.                     800,800,800,800,800,800,800,1600,
  365.                     800,800,800,800,800,800,800,4,0 };
  366.  
  367. UWORD hourtune[]={ 800,1600,800,1600,800,1600,800,1600,
  368.                    800,1600,800,1600,800,1600,800,1600,
  369.                    800,1600,800,1600,800,1600,800,4,0 };
  370.  
  371. UWORD quartertune[]={ 400,400,400,400,400,4,0 };
  372.  
  373. char pattern[]=
  374. "/M,TOP/N,LEFT/N,WIDTH/N,HEIGHT/N,SECONDS/S,PATTERN/K,OVAL/S,SHADOW/S,"
  375. "SHOWFACE/N,HANDTYPE/N,HANDWIDTH/N,DRAWPENS/K,BORDERTYPE/N,CHIME/N,"
  376. "PUBSCREEN/K,TASKPRI/N";
  377.  
  378. char *tooltypes[]={
  379. "TOP","LEFT","WIDTH","HEIGHT","SHOWFACE","HANDTYPE","HANDWIDTH","BORDERTYPE",
  380. "CHIME","SECONDS","OVAL","SHADOW","DRAWPENS","PATTERN" };
  381.  
  382. void wbmain(struct WBStartup *message)
  383. { main(0,(char **)message); }
  384.  
  385. void main(int argc,char *argv[])
  386. { ULONG class;
  387.   UWORD code;
  388.   ULONG signals;
  389.   UWORD check;
  390.   struct MenuItem *item,*item2;
  391.   openlibs();
  392.   if (!argc) /* Start von Workbench */
  393.     mergetooltypes((struct WBStartup *)argv);
  394.   else
  395.     parsecliargs(NULL,0);
  396.   openall();
  397.  
  398.   nexttick();
  399.   rahmen();
  400.   zifferblatt ();
  401.   zeichnen ();
  402.   for (;;)
  403.   { signals=Wait(1<<tport->mp_SigBit| /* Timer-Signal */
  404.                  1<<audport->mp_SigBit| /* Audio-Device */
  405.                  1<<mywindow->UserPort->mp_SigBit| /* IDCMP-Signal */
  406.                  SIGBREAKF_CTRL_C); /* User-Break */
  407.     if (GetMsg(tport)) /* Timer-Signal ? */
  408.     { if (nexttick())
  409.       { zifferblatt();
  410.         testifalarm(); }
  411.       zeichnen(); }
  412.     if (GetMsg(audport)) /* Audio */
  413.       playnote();
  414.     while (msg=(struct IntuiMessage *)GetMsg(mywindow->UserPort))
  415.     { class=msg->Class;
  416.       code=msg->Code;
  417.       ReplyMsg ((struct Message *)msg);
  418.       switch (class)
  419.       { case NEWSIZE:
  420.           newsize1();
  421.           newsize2();
  422.           rahmen();
  423.           zifferblatt ();
  424.           zeichnen ();
  425.           break;
  426.         case REFRESHWINDOW:
  427.           redrawx1=boleft;
  428.           redrawy1=botop;
  429.           redrawx2=boleft+breit2-1;
  430.           redrawy2=botop +hoehe2-1;
  431.           BeginRefresh(mywindow);
  432.           rahmen();
  433.           zeichnen();
  434.           EndRefresh(mywindow,TRUE);
  435.           break;
  436.         case MENUPICK:
  437.           while (code!=MENUNULL)
  438.           { if (!(item=ItemAddress(menus,code)))
  439.               closeall(RETURN_FAIL);
  440.             check=item->Flags&CHECKED;
  441.             switch (code)
  442.             { case FULLMENUNUM(0,0,NOSUB): /* About */
  443.                 AutoRequest(NULL,&about,NULL,&oktext,0,0,0,0);
  444.                 break;
  445.               case FULLMENUNUM(0,1,NOSUB): /* Save Prefs */
  446.                 if (!argc)
  447.                   cdtoicon((struct WBStartup *)argv); /* Von Workbench */
  448.                 else
  449.                   saveprefs(argv[0]); /* Von CLI */
  450.                 break;
  451.               case FULLMENUNUM(0,2,NOSUB): /* Quit */
  452.                 closeall(RETURN_OK);
  453.               case FULLMENUNUM(1,0,NOSUB): /* Menu Seconds ausgewΣhlt */
  454.                 sekunden=check;
  455.                 if (timesent)
  456.                 { AbortIO((iorequest)treq);
  457.                   WaitIO((iorequest)treq);
  458.                   timesent=0; }
  459.                 nexttick();
  460.                 break;
  461.               case FULLMENUNUM(1,1,NOSUB): /* oval umschalten */
  462.                 oval=check;
  463.                 break;
  464.               case FULLMENUNUM(1,2,0): /* zifferblatt */
  465.               case FULLMENUNUM(1,2,1):
  466.               case FULLMENUNUM(1,2,2):
  467.               case FULLMENUNUM(1,2,3):
  468.               case FULLMENUNUM(1,2,4):
  469.                 if (check)
  470.                   zeigen=SUBNUM(code);
  471.                 break;
  472.               case FULLMENUNUM(1,3,0): /* zeiger */
  473.               case FULLMENUNUM(1,3,1):
  474.               case FULLMENUNUM(1,3,2):
  475.               case FULLMENUNUM(1,3,3):
  476.                 if (check)
  477.                   zeigertyp=SUBNUM(code);
  478.                 break;
  479.               case FULLMENUNUM(1,3,5): /* zeigerbreite */
  480.               case FULLMENUNUM(1,3,6):
  481.               case FULLMENUNUM(1,3,7):
  482.               case FULLMENUNUM(1,3,8):
  483.               case FULLMENUNUM(1,3,9):
  484.                 if (check)
  485.                   zeigerbreite=SUBNUM(code)-5;
  486.                 break;
  487.               case FULLMENUNUM(1,4,NOSUB): /* Shadow */
  488.                 schatten=check;
  489.                 break;
  490.               case FULLMENUNUM(1,5,0): /* Rahmen */
  491.               case FULLMENUNUM(1,5,1):
  492.               case FULLMENUNUM(1,5,2):
  493.                 if (check)
  494.                   rahmenanz=SUBNUM(code);
  495.                 break;
  496.               case FULLMENUNUM(1,5,4):
  497.                 hires=check;
  498.                 break;
  499.               case FULLMENUNUM(1,5,5):
  500.                 interlace=check;
  501.                 break;
  502.               case FULLMENUNUM(1,6,0): /* Chime */
  503.               case FULLMENUNUM(1,6,1):
  504.               case FULLMENUNUM(1,6,2):
  505.                 if (check)
  506.                   chime=SUBNUM(code);
  507.                 break;
  508.               case FULLMENUNUM(1,6,4):
  509.                 smarthour=check;
  510.                 break;
  511.               case FULLMENUNUM(1,7,0): /* Alarm set */
  512.                 setalarm();
  513.                 item2=ItemAddress(menus,FULLMENUNUM(1,7,1));
  514.                 ClearMenuStrip(mywindow); /* Menu entfernen */
  515.                 item2->Flags&=~CHECKED;    /* Flags anpassen */
  516.                 if (alarm)
  517.                   item2->Flags|=CHECKED;
  518.                 ResetMenuStrip(mywindow,menus); /* Menu wieder einfⁿgen */
  519.                 break;
  520.               case FULLMENUNUM(1,7,1):
  521.                 alarm=check;
  522.                 break;
  523.               default:
  524.                 if (MENUNUM(code)==2)
  525.                 { getcolor(&pens[ITEMNUM(code)]);
  526.                   break; }
  527.                 if (MENUNUM(code)==3)
  528.                 { getcolor(&must[ITEMNUM(code)]);
  529.                   setpattern();
  530.                   break; }
  531.                 break;
  532.             } /* switch menus */
  533.             code=item->NextSelect;
  534.           } /* while */
  535.           newsize1(); /* Zwar manchmal unn÷tig, aber kurz */
  536.           newsize2();
  537.           rahmen();
  538.           zifferblatt();
  539.           zeichnen();
  540.           break;
  541.         case ACTIVEWINDOW:
  542.           active=1;
  543.           rahmen();
  544.           break;
  545.         case INACTIVEWINDOW:
  546.           active=0;
  547.           rahmen();
  548.           break;
  549.         case CLOSEWINDOW:
  550.           closeall(RETURN_OK);
  551.       } /* switch*/
  552.     } /* if */
  553.     if (signals&SIGBREAKF_CTRL_C) /* User-Break */
  554.       closeall(RETURN_WARN);
  555.   } /* for */
  556. } /* main */
  557.  
  558. void mergetooltypes(struct WBStartup *args)
  559. { int i,k;
  560.   BPTR oldlock;
  561.   char *newmem;
  562.   char **ttypes;
  563.   if (!args->sm_ArgList) /* Was da wohl fⁿr eine Arglist dahintersteckt ? */
  564.     return;
  565.   oldlock=CurrentDir(args->sm_ArgList->wa_Lock); /* CD */
  566.   dobj=GetDiskObjectNew(args->sm_ArgList->wa_Name);
  567.   CurrentDir(oldlock); /* nur zur Sicherheit */
  568.   if (!dobj)
  569.     closeall(RETURN_FAIL);
  570.   ttypes=dobj->do_ToolTypes;
  571.   strln=1;
  572.   if (!(string=AllocMem(strln,MEMF_ANY|MEMF_CLEAR)))
  573.     closeall(RETURN_FAIL);
  574.   for (i=0;ttypes[i];i++)
  575.   { for (k=0;ttypes[i][k];k++) /* LΣnge ermitteln */
  576.       ;
  577.     if (!(newmem=AllocMem(strln+k+1,MEMF_ANY|MEMF_CLEAR))) /* Neuer String */
  578.       closeall(RETURN_FAIL);
  579.     sprintf(newmem,"%s %s",string,ttypes[i]);
  580.     FreeMem(string,strln);
  581.     string=newmem;
  582.     strln+=k+1;
  583.   } /* for */
  584.   FreeDiskObject(dobj);
  585.   dobj=NULL;
  586.   parsecliargs(string,strln-1);
  587.   FreeMem(string,strln);
  588.   string=NULL;
  589. } /* mergetooltypes */
  590.  
  591. void parsecliargs(char *argstring,int laenge)
  592. { struct RDArgs *args1;
  593.   ULONG *erg;
  594.   args.RDA_Source.CS_Buffer=argstring;
  595.   args.RDA_Source.CS_Length=laenge;
  596.   args1=ReadArgs(argstring?pattern:&pattern[3],ergebnis,&args);
  597.   if (!argstring && !args1) /* Fehler in der Kommandozeile */
  598.     closeall(RETURN_FAIL);
  599.   erg=(argstring?&ergebnis[1]:ergebnis);
  600.   if (erg[0])
  601.     oben  =*(LONG *)erg[0];
  602.   if (erg[1])
  603.     links =*(LONG *)erg[1];
  604.   if (erg[2])
  605.     breite=*(LONG *)erg[2];
  606.   if (erg[3])
  607.     hoehe =*(LONG *)erg[3];
  608.   if (erg[4])
  609.     sekunden=1;
  610.   if (erg[5])
  611.     readstr(must,(char *)erg[5],4);
  612.   if (erg[6])
  613.     oval=1;
  614.   if (erg[7])
  615.     schatten=1;
  616.   if (erg[8])
  617.     zeigen=*(LONG *)erg[8];
  618.   if (erg[9])
  619.     zeigertyp=*(LONG *)erg[9];
  620.   if (erg[10])
  621.     zeigerbreite=*(LONG *)erg[10];
  622.   if (erg[11])
  623.     readstr(pens,(char *)erg[11],14);
  624.   if (erg[12])
  625.     rahmenanz=*(LONG *)erg[12];
  626.   if (erg[13])
  627.     chime=*(LONG *)erg[13];
  628.   pubscreen=LockPubScreen((char *)erg[14]); /* 0 gibt Default-PubScreen */
  629.   if (erg[15])
  630.   { oldpri=SetTaskPri(FindTask(NULL),*(LONG *)erg[15]);
  631.     changedpri=1; }
  632.   if (!argstring)
  633.     FreeArgs(args1);
  634.   else
  635.     FreeArgs(&args);
  636.   setargs();
  637. } /* parsecliargs */
  638.  
  639. void readstr(char *dest,char *sorc,int n)
  640. { if (*sorc=='x'||*sorc=='X') /* Hexadezimal */
  641.     while (n-- && *sorc++ && *sorc++)
  642.       *dest++=(xtod(sorc[-1])<<4)+xtod(*sorc);
  643.   else
  644.     while (*sorc && n--) /* Dezimal */
  645.       *dest++=xtod(*sorc++);
  646. } /* readstr */
  647.  
  648. int xtod(int a)
  649. { if (a>='0' && a<='9')
  650.     return(a-'0');
  651.   if (a>='a' && a<='f')
  652.     return(a-'a'+10);
  653.   if (a>='A' && a<='F')
  654.     return(a-'A'+10);
  655.   return(0);
  656. } /* xtod */
  657.  
  658. void setargs(void)
  659. { if (breite<10)/* Zu schmal ? */
  660.     breite=10;
  661.   if (hoehe<10)
  662.     hoehe=10;
  663.   if (zeigen<0 || zeigen>4)
  664.     zeigen=0;
  665.   if (zeigertyp<0 || zeigertyp>3)
  666.     zeigertyp=0;
  667.   if (zeigerbreite<0 || zeigerbreite>4)
  668.     zeigerbreite=0;
  669.   if (rahmenanz<0 || rahmenanz>5)
  670.     rahmenanz=0;
  671.   if (chime<0 || chime>4)
  672.     chime=0;
  673.   if (chime>2)
  674.   { smarthour=1;
  675.     chime-=2; }
  676.   if (rahmenanz>2)
  677.   { hires=rahmenanz&1;
  678.     interlace=rahmenanz>3;
  679.     rahmenanz=2; }
  680.   setpattern();
  681. } /* setargs */
  682.  
  683. void setpattern(void)
  684. { int i,a,b,c,d;
  685.   a=must[0];
  686.   b=must[1];
  687.   c=must[2];
  688.   d=must[3];
  689.   if (a==b && c==d) /* nur horizontale Streifen */
  690.     maskx=0xffffffff;
  691.   else
  692.     maskx=0xfffffffe;
  693.   if (a==c && b==d) /* nur vertikale Streifen */
  694.     masky=0xffffffff;
  695.   else
  696.     masky=0xfffffffe;
  697.   for (i=0;i<8;i++)
  698.   { muster[i][0]=(a&1<<i?0x5555:0)|(b&1<<i?0xaaaa:0);
  699.     muster[i][1]=(c&1<<i?0x5555:0)|(d&1<<i?0xaaaa:0); }
  700. } /* setpattern */
  701.  
  702. int nexttick(void)
  703. { ULONG oldmin;
  704.   treq->tr_node.io_Command=TR_GETSYSTIME;
  705.   DoIO((iorequest)treq);/* Zeit besorgen */
  706.   treq->tr_time.tv_micro=1100000-treq->tr_time.tv_micro;
  707.   sec=treq->tr_time.tv_secs; /* ^ Ein ganz besonders netter Effekt: Das Timerdevice */
  708.   treq->tr_time.tv_secs=(sekunden?0:59-sec%60); /* rundet aktuelle Zeit und Wartezeit ab */
  709.   treq->tr_node.io_Command=TR_ADDREQUEST;
  710.   SendIO((iorequest)treq); /* Und abschicken */
  711.   oldmin=min;
  712.   min=sec/60;
  713.   sec=sec%60;
  714.   std=min/12;
  715.   min=min%60;
  716.   std=std%60;
  717.   timesent=1;
  718.   return (oldmin!=min); /* sec==0 ist unzuverlΣssig bei hoher CPU-Auslastung */
  719. } /* nexttick */
  720.  
  721. void openlibs(void)
  722. { if (!(DOSBase=OpenLibrary("dos.library",37)))
  723.     closeall(RETURN_FAIL);
  724.   if (!(GfxBase=OpenLibrary("graphics.library",37)))
  725.     closeall(RETURN_FAIL);
  726.   if (!(IntuitionBase=OpenLibrary("intuition.library",37)))
  727.     closeall(RETURN_FAIL);
  728.   if (!(GadToolsBase=OpenLibrary("gadtools.library",37)))
  729.     closeall(RETURN_FAIL);
  730.   if (!(IconBase=OpenLibrary("icon.library",37)))
  731.     closeall(RETURN_FAIL);
  732. } /* openlibs */
  733.  
  734. void openall(void)
  735. { /* Libraries sind schon ge÷ffnet, PubScreen schon blockiert */
  736.   if (!(tport=CreateMsgPort()))/* Port fⁿr Timer */
  737.     closeall(RETURN_FAIL);
  738.   if (!(treq=CreateIORequest(tport,sizeof(struct timerequest))))
  739.     closeall(RETURN_FAIL);
  740.   if (notime=OpenDevice(TIMERNAME,UNIT_VBLANK,(iorequest)treq,0))
  741.     closeall(RETURN_FAIL);
  742.   if (!(audport=CreateMsgPort()))/* Replyport fⁿr audio.device */
  743.     closeall(RETURN_FAIL);
  744.   if (!(audreq[0]=CreateIORequest(audport,sizeof(struct IOAudio))))
  745.     closeall(RETURN_FAIL);
  746.   if (!(audreq[1]=CreateIORequest(audport,sizeof(struct IOAudio))))
  747.     closeall(RETURN_FAIL);
  748.   if (noaudio=OpenDevice(AUDIONAME,0,(iorequest)audreq[0],0))
  749.     closeall(RETURN_FAIL);
  750.   if (!(waveform=AllocMem(8,MEMF_CHIP|MEMF_CLEAR)))
  751.     closeall(RETURN_FAIL);
  752.   waveform[0]=waveform[2]=127; /* Rechteck */
  753.   waveform[1]=waveform[3]=-128;
  754.   if (!(visi=GetVisualInfoA(pubscreen,notags)))
  755.     closeall(RETURN_FAIL);
  756.   if (sekunden)
  757.     menulist[5].nm_Flags|=CHECKED;
  758.   if (oval)
  759.     menulist[6].nm_Flags|=CHECKED;
  760.   if (schatten)
  761.     menulist[24].nm_Flags|=CHECKED;
  762.   if (hires)
  763.     menulist[30].nm_Flags|=CHECKED;
  764.   if (interlace)
  765.     menulist[31].nm_Flags|=CHECKED;
  766.   if (smarthour)
  767.     menulist[37].nm_Flags|=CHECKED;
  768.   menulist[8+zeigen].nm_Flags|=CHECKED;
  769.   menulist[14+zeigertyp].nm_Flags|=CHECKED;
  770.   menulist[19+zeigerbreite].nm_Flags|=CHECKED;
  771.   menulist[26+rahmenanz].nm_Flags|=CHECKED;
  772.   menulist[33+chime].nm_Flags|=CHECKED;
  773.   if (!(menus=CreateMenusA(menulist,notags)))
  774.     closeall(RETURN_FAIL);
  775.   if (!LayoutMenusA(menus,visi,notags))
  776.     closeall(RETURN_FAIL);
  777.   windowtags[0].ti_Data=links;
  778.   windowtags[1].ti_Data=oben;
  779.   windowtags[2].ti_Data=breite;
  780.   windowtags[3].ti_Data=hoehe;
  781.   windowtags[4].ti_Data=(ULONG)pubscreen;
  782.   if (!(mywindow=OpenWindowTagList(NULL,windowtags)))
  783.     closeall(RETURN_FAIL);
  784.   SetMenuStrip(mywindow,menus);
  785.   rport1=mywindow->RPort;
  786.   SetAPen(rport1,pens[0]);
  787.   newsize2();
  788. } /* openall */
  789.  
  790. void closeall(int retval) /* AufrΣumen */
  791. { newsize1(); /* Bitmaps l÷schen */
  792.   if (string)
  793.     FreeMem(string,strln);
  794.   if (dobj)
  795.     FreeDiskObject(dobj);
  796.   if (mywindow) /* Window schlie▀en */
  797.   { ClearMenuStrip(mywindow);
  798.     CloseWindow(mywindow); }
  799.   if (menus)
  800.     FreeMenus(menus);
  801.   if (visi)
  802.     FreeVisualInfo(visi);
  803.   if (pubscreen)
  804.     UnlockPubScreen(NULL,pubscreen);
  805.   if (waveform)
  806.     FreeMem(waveform,8);
  807.   if (audsent[0])
  808.   { AbortIO((iorequest)audreq[0]); /* Ton abbrechen */
  809.     WaitIO((iorequest)audreq[0]); }
  810.   if (audsent[1])
  811.   { AbortIO((iorequest)audreq[1]); /* Ton abbrechen */
  812.     WaitIO((iorequest)audreq[1]); }
  813.   if (!nosound)
  814.     endtune();
  815.   if (!noaudio)
  816.     CloseDevice((iorequest)audreq[0]);
  817.   if (audreq[1])
  818.     DeleteIORequest(audreq[1]);
  819.   if (audreq[0])
  820.     DeleteIORequest(audreq[0]);
  821.   if (audport)
  822.     DeleteMsgPort(audport);
  823.   if (timesent)
  824.   { AbortIO((iorequest)treq);
  825.     WaitIO((iorequest)treq); }
  826.   if (!notime) /* Timerequest abbrechen */
  827.     CloseDevice((iorequest)treq);
  828.   if (treq)
  829.     DeleteIORequest(treq);
  830.   if (tport)
  831.     DeleteMsgPort(tport);
  832.   if (changedpri)
  833.     SetTaskPri(FindTask(NULL),oldpri);
  834.   if (IconBase)
  835.     CloseLibrary(IconBase);
  836.   if (GadToolsBase)
  837.     CloseLibrary(GadToolsBase);
  838.   if (GfxBase)
  839.     CloseLibrary(GfxBase);
  840.   if (IntuitionBase)
  841.     CloseLibrary(IntuitionBase);
  842.   if (DOSBase)
  843.     CloseLibrary(DOSBase);
  844.   exit(retval); /* Fertig */
  845. } /* closeall */
  846.  
  847. void newsize2(void) /* Holt BitPlanes */
  848. { int i,k;
  849.   static long gadgsize=-1;
  850.   long newsize;
  851.   boleft=rahmenanz+(hires    ?(rahmenanz==2)<<1:0);
  852.   botop =rahmenanz+(interlace?(rahmenanz==2)<<1:0);
  853.   breite=mywindow->Width;
  854.   hoehe =mywindow->Height;
  855.   breit2=breite-(boleft<<1);
  856.   hoehe2=hoehe -(botop <<1);
  857.   doublex=(maskx==-2&&breit2>12);
  858.   doubley=(masky==-2&&hoehe2>12);
  859.   xoffset=(breit2>50?2:(breit2>25?1:0));
  860.   yoffset=(hoehe2>50?2:(hoehe2>25?1:0));
  861.   newsize=(breite<hoehe?breite/8:hoehe/8);
  862.   if (newsize!=gadgsize)
  863.   { gadgsize=newsize; /* Gadgets mⁿssen in der Gr÷▀e angepasst werden */
  864.     RemoveGList(mywindow,gadgets,-1);
  865.     for (i=0;i<4;i++)
  866.       for (k=0;k<4;k++) /* Casting ist nicht sch÷n, aber wirksam */
  867.         ((SHORT *)&gadgets[i].LeftEdge)[k]=sizes[i][k]*gadgsize;
  868.     AddGList(mywindow,gadgets,0,4,NULL);
  869.   } /* if */
  870.   InitBitMap(&abitmap,mywindow->WScreen->BitMap.Depth,breit2,hoehe2);
  871.   for (i=0;i<abitmap.Depth;i++)
  872.     if (!(abitmap.Planes[i]=AllocRaster(breit2,hoehe2)))
  873.       closeall(RETURN_FAIL);
  874.   InitRastPort(&rport2);
  875.   rport2.BitMap=&abitmap;
  876.   if (!(buf=AllocRaster(breit2,hoehe2)))
  877.     closeall(RETURN_FAIL);
  878.   rport2.TmpRas=InitTmpRas (&temp,buf,RASSIZE(breit2,hoehe2));
  879.   InitArea (&info,table,5);
  880.   rport2.AreaInfo=(struct AreaInfo *)&info;
  881. } /* newsize2 */
  882.  
  883. void newsize1(void) /* L÷scht BitPlanes */
  884. { int i;
  885.   if (buf)
  886.   { FreeRaster(buf,breit2,hoehe2);
  887.     buf=NULL; }
  888.   for (i=0;i<abitmap.Depth;i++)
  889.   if (abitmap.Planes[i])
  890.   { FreeRaster(abitmap.Planes[i],breit2,hoehe2);
  891.     abitmap.Planes[i]=NULL; }
  892. } /* newsize1 */
  893.  
  894. void zifferblatt (void)
  895. { int i,a,b,c;
  896.   long x0,y0,x,y;
  897.  
  898.   BNDRYOFF (&rport2); /* Hintergrund */
  899.   SetAPen  (&rport2,-1);
  900.   SetAfPt  (&rport2,*muster,-1);
  901.   RectFill (&rport2,0,0,breit2-1,hoehe2-1);
  902.   SetAfPt  (&rport2,0,0);
  903.  
  904.   x0=breit2/2;
  905.   y0=hoehe2/2;
  906.  
  907.   a=(zeigen>1?(zeigen==3?60:15):(zeigen?5:1));
  908.   if (zeigen<4)
  909.     for (i=0;i<60;i+=a)
  910.     { x=x0+((oval?  sinus[i]:srect[i])*breit2/300)&maskx;/* Position des Striches */
  911.       y=y0-((oval?cosinus[i]:crect[i])*hoehe2/300)&masky;
  912.       if (i%5)
  913.       { if (i%5==1)
  914.         { c=pens[9];
  915.           SetAPen(&rport2,c);
  916.           SetOPen(&rport2,c); }
  917.         AreaMove (&rport2,x+breit2/200,y);
  918.         AreaDraw (&rport2,x,y+hoehe2/200);
  919.         AreaDraw (&rport2,x-breit2/200,y);
  920.         AreaDraw (&rport2,x,y-hoehe2/200);
  921.         AreaEnd  (&rport2);
  922.       } else
  923.       { b=i/5;
  924.         c=pens[pent[b]];
  925.         SetAPen(&rport2,c);
  926.         SetOPen(&rport2,c);
  927.         AreaMove (&rport2,x+=breit2*dx1[b]/100,y+=hoehe2*dy1[b]/100);
  928.         AreaDraw (&rport2,x+=breit2*dx2[b]/100,y+=hoehe2*dy2[b]/100);
  929.         AreaDraw (&rport2,x+=breit2*dx3[b]/100,y+=hoehe2*dy3[b]/100);
  930.         AreaDraw (&rport2,x+=breit2*dx4[b]/100,y+=hoehe2*dy4[b]/100);
  931.         AreaEnd  (&rport2);
  932.       } /* if */
  933.     } /* for */
  934.   if (schatten)
  935.   { zeiger(std,440,1,pens[5],pens[5]);
  936.     zeiger(min,300,1,pens[5],pens[5]); }
  937.   zeiger(std,440,0,pens[3],pens[4]);
  938.   zeiger(min,300,0,pens[1],pens[2]);
  939.  
  940.   redrawx1=boleft;
  941.   redrawy1=botop;
  942.   redrawx2=boleft+breit2-1;
  943.   redrawy2=botop +hoehe2-1;
  944. } /* zifferblatt */
  945.  
  946. void rahmen(void)
  947. { if (rahmenanz)
  948.   { SetAPen(rport1,(active&&rahmenanz==1)?pens[12]:pens[11]);
  949.     Move(rport1,1            ,hoehe-1    );
  950.     Draw(rport1,breite-1     ,hoehe-1    );
  951.     Draw(rport1,breite-1     ,1          );
  952.     SetAPen(rport1,(active&&rahmenanz==1)?pens[11]:pens[12]);
  953.     Move(rport1,0,            hoehe-1    );
  954.     Draw(rport1,0,            0          );
  955.     Draw(rport1,breite-1,     0          );
  956.     if (rahmenanz==2)
  957.     { SetAPen(rport1,pens[12]); /* Rahmen */
  958.       Move(rport1,boleft       ,hoehe-botop);
  959.       Draw(rport1,breite-boleft,hoehe-botop);
  960.       Draw(rport1,breite-boleft,botop      );
  961.       SetAPen(rport1,pens[11]);
  962.       Move(rport1,boleft-1     ,hoehe-botop);
  963.       Draw(rport1,boleft-1     ,botop-1    );
  964.       Draw(rport1,breite-boleft,botop-1    );
  965.       SetAPen(rport1,active?pens[13]:pens[10]);
  966.       if (hires)
  967.       { RectFill(rport1,1,1,2,hoehe-2);
  968.         RectFill(rport1,breite-3,1,breite-2,hoehe-2); }
  969.       if (interlace)
  970.       { RectFill(rport1,1,1,breite-2,2);
  971.         RectFill(rport1,1,hoehe-3,breite-2,hoehe-2); }
  972.     } /* if */
  973.   } /* if */
  974.   SetAPen(rport1,pens[0]);
  975. } /* rahmen */
  976.  
  977. void zeiger(ULONG winkel,int lfactor,int offset,int apen,int open)
  978. { long x0,y0,x1,y1,x2,y2;
  979.   x0=breit2/2+(offset?xoffset:0);
  980.   y0=hoehe2/2+(offset?yoffset:0);
  981.   x2=sinus  [winkel]*breit2/lfactor;
  982.   y2=cosinus[winkel]*hoehe2/lfactor;
  983.   x1=cosinus[winkel]*breit2/handwidth[zeigerbreite];
  984.   y1=sinus  [winkel]*hoehe2/handwidth[zeigerbreite];
  985.   SetAPen(&rport2,apen);
  986.   SetOPen(&rport2,open);
  987.   switch (zeigertyp)
  988.   { case 0:
  989.       SetAPen(&rport2,open);
  990.       Move (&rport2,x0,y0);
  991.       Draw (&rport2,x0+x2,y0-y2);
  992.       if (doublex)
  993.       { Move (&rport2,1+x0,y0);
  994.         Draw (&rport2,1+x0+x2,y0-y2); }
  995.       if (doubley)
  996.       { Move (&rport2,x0,1+y0);
  997.         Draw (&rport2,x0+x2,1+y0-y2); }
  998.       break;
  999.     case 1:
  1000.       AreaMove (&rport2,x0+x2     ,y0-y2     );
  1001.       AreaDraw (&rport2,x0+x1-x2/4,y0+y1+y2/4);
  1002.       AreaDraw (&rport2,x0-x1-x2/4,y0-y1+y2/4);
  1003.       AreaEnd  (&rport2);
  1004.       break;
  1005.     case 2:
  1006.       AreaMove (&rport2,x0+x2  ,y0-y2  );
  1007.       AreaDraw (&rport2,x0+x1  ,y0+y1  );
  1008.       AreaDraw (&rport2,x0-x2/4,y0+y2/4);
  1009.       AreaDraw (&rport2,x0-x1  ,y0-y1  );
  1010.       AreaEnd  (&rport2);
  1011.       break;
  1012.     case 3:
  1013.       AreaMove (&rport2,x0+=x2-x1/2,y0-=y2+y1/2);
  1014.       AreaDraw (&rport2,x0+=x1     ,y0+=y1     );
  1015.       AreaDraw (&rport2,x0-=x2*5/4 ,y0+=y2*5/4 );
  1016.       AreaDraw (&rport2,x0-=x1     ,y0-=y1     );
  1017.       AreaEnd  (&rport2);
  1018.       break;
  1019.   } /* switch */
  1020. } /* zeiger */
  1021.  
  1022. void zeichnen(void)
  1023. { long tmp;
  1024.   BltBitMapRastPort(&abitmap,redrawx1-boleft,redrawy1-botop,
  1025.                     rport1,redrawx1,redrawy1,
  1026.                     redrawx2-redrawx1+1,redrawy2-redrawy1+1,0xc0);
  1027.   if (sekunden)
  1028.   { redrawx1=breite/2;
  1029.     redrawy1=hoehe /2;
  1030.     redrawx2=redrawx1+sinus  [sec]*breit2/300;
  1031.     redrawy2=redrawy1-cosinus[sec]*hoehe2/300;
  1032.     Move(rport1,redrawx1,redrawy1);
  1033.     Draw(rport1,redrawx2,redrawy2);
  1034.     if (doublex)
  1035.     { Move(rport1,1+redrawx1,redrawy1);
  1036.       Draw(rport1,1+redrawx2,redrawy2); }
  1037.     if (doubley)
  1038.     { Move(rport1,redrawx1,1+redrawy1);
  1039.       Draw(rport1,redrawx2,1+redrawy2); }
  1040.     if (redrawx1>redrawx2)
  1041.     { tmp=redrawx1;
  1042.       redrawx1=redrawx2;
  1043.       redrawx2=tmp; }
  1044.     if (redrawy1>redrawy2)
  1045.     { tmp=redrawy1;
  1046.       redrawy1=redrawy2;
  1047.       redrawy2=tmp; }
  1048.     if (doublex)
  1049.       redrawx2++;
  1050.     if (doubley)
  1051.       redrawy2++;
  1052.   } /* if */
  1053. } /* zeichnen */
  1054.  
  1055. void getcolor(UBYTE *color)
  1056. { struct Window *window;
  1057.   struct Gadget *gadgets;
  1058.   struct IntuiMessage *msg;
  1059.   window2gadtags1[0].ti_Data=abitmap.Depth;
  1060.   if (window=creatertrequest(window2tags,1,window2gadtags,
  1061.                              window2gad,window2goff,&gadgets))
  1062.   { WaitPort(window->UserPort);
  1063.     msg=GT_GetIMsg(window->UserPort);
  1064.     if (msg->Class==GADGETUP) /* kann nur das Palette-Gadget sein */
  1065.       *color=msg->Code;
  1066.     GT_ReplyIMsg(msg);
  1067.     CloseWindow(window);
  1068.   } /* if */
  1069.   FreeGadgets(gadgets);
  1070. } /* getcolor */
  1071.  
  1072. void setalarm(void)
  1073. { struct Window *window;
  1074.   struct Gadget *gadgets;
  1075.   struct IntuiMessage *msg;
  1076.   ULONG class,st,mi;
  1077.   st=window3gadtags1[0].ti_Data=alstd;
  1078.   mi=window3gadtags2[0].ti_Data=almin;
  1079.   if (window=creatertrequest(window3tags,4,window3gadtags,
  1080.                              window3gad,window3goff,&gadgets))
  1081.   { do
  1082.     { WaitPort(window->UserPort);
  1083.       msg=GT_GetIMsg(window->UserPort);
  1084.       class=msg->Class;
  1085.       if (class==MOUSEMOVE || class==GADGETUP)
  1086.       { switch(((struct Gadget *)(msg->IAddress))->GadgetID)
  1087.         { case 1:
  1088.             st=msg->Code;
  1089.             break;
  1090.           case 2:
  1091.             mi=msg->Code;
  1092.             break;
  1093.           case 3:
  1094.             alstd=st;
  1095.             almin=mi;
  1096.             alarm=1;
  1097.             class=CLOSEWINDOW;
  1098.             break;
  1099.           case 4:
  1100.             class=CLOSEWINDOW;
  1101.             break;
  1102.         } /* switch */
  1103.       } /* if */
  1104.       GT_ReplyIMsg(msg);
  1105.     } while (class!=CLOSEWINDOW);
  1106.     CloseWindow(window);
  1107.   } /* if */
  1108.   FreeGadgets(gadgets);
  1109. } /* getcolor */
  1110.  
  1111. struct Window *creatertrequest
  1112. ( struct TagItem windowtags[],int anzgadgets,struct TagItem *gadgettags[],
  1113.   struct NewGadget gadgets[],ULONG edge[][3],struct Gadget **glistpointer)
  1114. { struct Gadget *context;
  1115.   struct Window *window;
  1116.   int i;
  1117.   *glistpointer=NULL;
  1118.   if (context=CreateContext(glistpointer))
  1119.   { for (i=0;i<anzgadgets;i++)
  1120.     { gadgets[i].ng_LeftEdge=edge[i][0]+  mywindow->WScreen->WBorLeft;
  1121.       gadgets[i].ng_TopEdge =edge[i][1]+1+mywindow->WScreen->WBorTop+
  1122.                                         mywindow->WScreen->RastPort.TxHeight;
  1123.       gadgets[i].ng_VisualInfo=visi;
  1124.       if (!(context=CreateGadgetA(edge[i][2],context,
  1125.                                   &gadgets[i],gadgettags[i])))
  1126.         break;
  1127.     } /* for */
  1128.     if (i==anzgadgets)
  1129.     { windowtags[0].ti_Data=(ULONG)*glistpointer;
  1130.       windowtags[1].ti_Data=(ULONG)pubscreen;
  1131.       if (window=OpenWindowTagList(NULL,windowtags))
  1132.       { GT_RefreshWindow(window,NULL);
  1133.         return(window); }
  1134.     } /* if */
  1135.     if (*glistpointer)
  1136.       FreeGadgets(*glistpointer);
  1137.   } /* if */
  1138.   return(NULL);
  1139. } /* creatertrequest */
  1140.  
  1141. void cdtoicon(struct WBStartup *args)
  1142. { BPTR oldlock;
  1143.   if (!args->sm_ArgList) /* Was da wohl fⁿr eine Arglist dahintersteckt ? */
  1144.     return;
  1145.   oldlock=CurrentDir(args->sm_ArgList->wa_Lock); /* CD */
  1146.   saveprefs(args->sm_ArgList->wa_Name);
  1147.   CurrentDir(oldlock); /* nur zur Sicherheit */
  1148. } /* cdtoicon */
  1149.  
  1150. void saveprefs(char *myname)
  1151. { int i,k,a;
  1152.   char **ttypes1;
  1153.   char **ttypes2;
  1154.   ULONG size;
  1155.   if (dobj=GetDiskObjectNew(myname)) /* Tooltypes einlesen */
  1156.   { ttypes1=dobj->do_ToolTypes;
  1157.     for (i=0;ttypes1[i];i++) /* Tooltypes zΣhlen */
  1158.       ;
  1159.     size=i*sizeof(char *)+sizeof(tooltypes); /* sizeof() 4 bytes pro pointer */
  1160.     if (ttypes2=AllocMem(size,MEMF_ANY|MEMF_CLEAR))
  1161.     { CopyMem(ttypes1,ttypes2,i*sizeof(char *));
  1162.       for (i=0;i<sizeof(tooltypes)/sizeof(char *);i++) /* Eigene Tooltypes */
  1163.       { if (FindToolType(ttypes2,tooltypes[i]))        /* entfernen */
  1164.         { for (k=1;ttypes2[k]&&FindToolType(&ttypes2[k],tooltypes[i]);k++)
  1165.             ;
  1166.           for (k--;ttypes2[k];k++)
  1167.             ttypes2[k]=ttypes2[k+1]; }
  1168.       } /* for */
  1169.       for (i=0;ttypes2[i];i++) /* Tooltypes zΣhlen */
  1170.         ;
  1171.       for (k=0;k<sizeof(tooltypes)/sizeof(char *);k++) /* je 39 Bytes holen */
  1172.         if (!(ttypes2[i+k]=AllocMem(39,MEMF_ANY|MEMF_CLEAR)))
  1173.           break;
  1174.       if (k==sizeof(tooltypes)/sizeof(char *)) /* Alles Allokiert */
  1175.       { a=i;
  1176.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[0],mywindow->TopEdge);
  1177.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[1],mywindow->LeftEdge);
  1178.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[2],breite);
  1179.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[3],hoehe);
  1180.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[4],zeigen);
  1181.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[5],zeigertyp);
  1182.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[6],zeigerbreite);
  1183.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[7],
  1184.           rahmenanz+(rahmenanz==2?(hires?1:0)+(interlace?2:0):0));
  1185.         sprintf(ttypes2[a++],"%s=%ld",tooltypes[8],chime+(chime&&smarthour?2:0));
  1186.         if (sekunden)
  1187.           sprintf(ttypes2[a++],"%s",tooltypes[9]);
  1188.         if (oval)
  1189.           sprintf(ttypes2[a++],"%s",tooltypes[10]);
  1190.         if (schatten)
  1191.           sprintf(ttypes2[a++],"%s",tooltypes[11]);
  1192.         sprintf(ttypes2[a],"%s=x",tooltypes[12]);
  1193.         setstr(&ttypes2[a++][10],pens,14);
  1194.         sprintf(ttypes2[a],"%s=x",tooltypes[13]);
  1195.         setstr(&ttypes2[a][9],must,4);
  1196.         dobj->do_ToolTypes=ttypes2;
  1197.         PutDiskObject(myname,dobj);
  1198.         dobj->do_ToolTypes=ttypes1;
  1199.       } /* if */
  1200.       for (;--k>0;) /* Freigeben */
  1201.         FreeMem(ttypes2[i+k],39);
  1202.       FreeMem(ttypes2,size);
  1203.     } /* if */
  1204.     FreeDiskObject(dobj);
  1205.     dobj=NULL;
  1206.   } /* if */
  1207. } /* saveprefs */
  1208.  
  1209. void setstr(char *dest,UBYTE *sourc,int n)
  1210. { while (n--)
  1211.   { *dest++=dtox(*sourc>>4);
  1212.     *dest++=dtox(*sourc++&0xf); }
  1213. } /* setstr */
  1214.  
  1215. int dtox(int a)
  1216. { if (a>9)
  1217.     return(a+'A'-10);
  1218.   else
  1219.     return(a+'0');
  1220. } /* dtox */
  1221.  
  1222. void testifalarm(void)
  1223. { ULONG st2;
  1224.   st2=std/5;
  1225.   if (!st2)
  1226.     st2=12;
  1227.   if (alarm && min==almin && st2==alstd)
  1228.     starttune(alarmtune);
  1229.   else if (chime && !min)
  1230.     starttune(&hourtune[smarthour?24-st2*2:22]);
  1231.   else if (chime==2 && (min==15 || min==30 || min==45))
  1232.     starttune(&quartertune[6-min/15*2]);
  1233. } /* testifalarm */
  1234.  
  1235. void starttune(UWORD *tune)
  1236. { if (!nosound) /* LΣuft schon einer */
  1237.     return;
  1238.   audreq[0]->ioa_Request.io_Command=ADCMD_ALLOCATE;
  1239.   audreq[0]->ioa_Request.io_Message.mn_Node.ln_Pri=90; /* ALARM-Level */
  1240.   audreq[0]->ioa_Request.io_Flags=ADIOF_NOWAIT;
  1241.   audreq[0]->ioa_Data=camap;
  1242.   audreq[0]->ioa_Length=4;
  1243.   BeginIO((iorequest)audreq[0]);
  1244.   if (nosound=WaitIO((iorequest)audreq[0]))
  1245.     return;
  1246.   CopyMem(audreq[0],audreq[1],sizeof(struct IOAudio));
  1247.   playtune=tune;
  1248.   playnote();
  1249.   playnote();
  1250. } /* starttune */
  1251.  
  1252. void playnote(void)
  1253. { static int requestnr=1;
  1254.   requestnr=!requestnr;
  1255.   audsent[requestnr]=0;
  1256.   if (!*playtune)
  1257.   { if (!audsent[!requestnr]) /* Anderer Request auch zurⁿck ? */
  1258.       endtune();
  1259.     return; }
  1260.   audreq[requestnr]->ioa_Request.io_Command=CMD_WRITE;
  1261.   audreq[requestnr]->ioa_Request.io_Flags=ADIOF_PERVOL;
  1262.   audreq[requestnr]->ioa_Data=&waveform[requestnr*4];
  1263.   audreq[requestnr]->ioa_Length=4;
  1264.   audreq[requestnr]->ioa_Period=500; /* ekliger Piepton */
  1265.   audreq[requestnr]->ioa_Volume=64;
  1266.   audreq[requestnr]->ioa_Cycles=*playtune++;
  1267.   BeginIO((iorequest)audreq[requestnr]);
  1268.   audsent[requestnr]=1; /* Merken */
  1269. } /* playnote */
  1270.  
  1271. void endtune(void)
  1272. { audreq[0]->ioa_Request.io_Command=ADCMD_FREE;
  1273.   DoIO((iorequest)audreq[0]);
  1274.   nosound=1;
  1275. } /* endtune */
  1276.